home *** CD-ROM | disk | FTP | other *** search
/ Precision Software Appli…tions Silver Collection 3 / Precision Software Applications Silver Collection Volume Three (PSM) (1993).iso / music2 / sb_osc.arj / OSC104.ASM next >
Assembly Source File  |  1992-01-22  |  16KB  |  503 lines

  1.  ;definable options when compiling :
  2.  ;
  3.  ;/dMAX   - Include Maximum Volume Indicator.
  4.  ;/dVOL   - Volume bar
  5.  ;/dDET   - Determine base-address yourself.
  6.  ;/dOVER  - Add base-address override function command line option /b:2
  7.  ;
  8.  ;if VOL is not defined, defining MAX will have no effect whatsoever.
  9.  ;
  10.  ;
  11.  ;
  12.  ;Osclilloscoop 1.04
  13.  ;
  14.  ;by : Ernst Teuling.
  15.  ;
  16.  ;Works for my sound blaster (base adress = 220h)
  17.  ;you can change adresses below to suit your sb.
  18.  ;
  19.  ;Version 1.00 : Full screen osc.
  20.  ;Version 1.01 : Use a window, show volume below.
  21.  ;Version 1.02 : Use 2 colors in volume bar, also made changing colors easy.
  22.  ;               Also added, a window around volume bar
  23.  ;Version 1.03 : Added a line which keeps max. volume for some time.
  24.  ;Version 1.04 : Added automatic base-adress detection
  25.  ;
  26.  ;
  27.  ;Note that this program doesn't reset the soundblaster, so some things might
  28.  ;react strange if you've run this.
  29.  ;
  30.  
  31. ifndef DET
  32.  BPORT  = 220H ;Base Port address
  33.  XPORT  = 226H ;Reset port address
  34.  WPORT  = 22CH ;Write port address
  35.  RPORT  = 22AH ;Read port address
  36.  APORT  = 22EH ;Data Available port address
  37. endif ;DET
  38.  READY  = 0AAH
  39.  
  40. Bordercolor =1                ;Window border
  41. OscColor    =15               ;Oscilloscope
  42. ifdef VOL
  43. VolumeColor1=2                ;First part of volume bar
  44. VolumeColor2=4                ;Second part of volume bar
  45. ifdef MAX
  46. MaxColor    =15               ;Max. Volume indicator.
  47. endif ;MAX
  48. endif ;VOL
  49.  
  50. .model small
  51. .stack 100h
  52. .data
  53. buffer     db 320 dup(0)
  54. text       db 'Oscilloscope 1.04',13,10
  55.            db '=================',13,10,10
  56.            db 'Compiled options : - Oscilloscope Window',13,10
  57. ifdef VOL
  58.            db '                   - Volume Bar',13,10
  59. ifdef MAX
  60.            db '                   - Max. Volume Indicator',13,10
  61. endif ;MAX
  62. endif ;VOL
  63. ifdef DET
  64.            db '                   - Auto-detection of Sound Blaster',13,10
  65. endif ;DET
  66. ifdef OVER
  67.            db '                   - Override base address switch',13,10
  68. endif ;OVER
  69.            db 13,10,10
  70.            db 'This program is freeware.',13,10,10
  71.            db 'Written by     : E.A.B.Teuling',13,10
  72.            db 'Compiled at    : RUU, using TASM 2.5 (have not bought it myself yet).',13,10
  73.            db 'Reactions to   : E.A.B.Teuling',13,10
  74.            db '                 Langebaan 40',13,10
  75.            db '                 4206 VP, Gorinchem',13,10
  76.            db '                 THE NETHERLANDS',13,10,10
  77.            db '$'
  78.  
  79. ifdef DET
  80. noblaster  db 'No SoundBlaster Found - Program aborted.',13,10,10,'$'
  81. endif ;DET
  82.  
  83. b_port     dw 0   ; Determined port adresses
  84. x_port     dw 0   ;
  85. w_port     dw 0   ;
  86. r_port     dw 0   ;
  87. a_port     dw 0   ;
  88.  
  89.  
  90. ifdef VOL
  91. ifdef MAX
  92. maxvolume  dw 0
  93. keeptime   dw 0
  94. endif ;MAX
  95. endif ;VOL
  96.  
  97. ifdef OVER
  98. ComOptions db 'Command Line Switches are :',13,10
  99.            db '/b:x   (where x is in range 1-6) indicates base address of SB.',13,10
  100.            db '       base address is found at : 2x0h'
  101.            db 13,10,10
  102.            db 'press any to continue.',13,10
  103.            db '$'
  104. endif ;OVER
  105.  
  106. .code
  107.  
  108. ifdef OVER
  109.   call  TestCommandLine       ;Test for presence of commandLine
  110.   pushf
  111. endif ;OVER
  112.  
  113.   mov   ax,@data
  114.   mov   ds,ax                 ;Make DS point to Data Segment
  115.   mov   ax,0a000h
  116.   mov   es,ax                 ;Make ES point to Screen Segment
  117.  
  118. ifdef OVER
  119.   popf                        ;If user specified a base address
  120.   jc    Overrided             ;then skip testing part.
  121. endif ;OVER
  122.  
  123. ifdef DET
  124.   call  InitialiseSB          ;Test for SB, and determine base address
  125.   jnc   BlasterIsFound        ;if found, then continue
  126.   mov   ah,4ch                ;else,....
  127.   int   21h                   ;Abort Program
  128. BlasterIsFound:
  129. endif ;DET
  130.  
  131. ifndef DET
  132.   mov   word ptr [b_port],bport         ;
  133.   mov   word ptr [x_port],xport         ;Initialise ports
  134.   mov   word ptr [w_port],wport         ;
  135.   mov   word ptr [r_port],rport         ;
  136.   mov   word ptr [a_port],aport         ;
  137. endif ;not DET
  138.  
  139. ifdef OVER
  140. overrided:
  141. endif ;OVER
  142.   mov   ax,13h
  143.   int   10h                   ;Change to mode 13h, MCGA 256 colors.
  144.   call  DrawBorder            ;Draw Window for the oscilloscope.
  145.   xor   si,si
  146.   inc   si
  147. ifdef VOL
  148.   xor   cx,cx                 ;Blank Volume bar
  149. endif ;VOL
  150. oncemore:
  151. ifdef VOL
  152.   push  cx
  153. endif ;VOL
  154.   push  si
  155.   mov   al,20h
  156.   mov   dx,[ds:w_port]
  157.   out   dx,al                 ;Tell SoundBlaster you wanna read a byte.
  158. GetMyByte:
  159.   mov   dx,[ds:a_port]
  160.   in    al,dx
  161.   cmp   al,127                ;Check if Sound Blaster wants to give you a byte.
  162.   je    GetMyByte
  163.   mov   dx,[ds:r_port]
  164.   in    al,dx                 ;Read a byte from SB
  165.   pop   si
  166. ifdef VOL
  167.   pop   cx
  168.   call  Add2VolumeBar         ;Adjust volume bar for this sound.
  169.   push  cx
  170. endif ;VOL
  171.   shr   al,1                  ;Divide by 2, for adjusting to Window size
  172.   push  ax
  173.   mov   al,[ds:si]            ;Read buffer for pixel to black out
  174.   xor   ah,ah
  175.   call  Paint                 ;Black Out Previous line
  176.   pop   ax
  177.   mov   [ds:si],al
  178.   mov   ah,OscColor
  179.   call  Paint                 ;Draw current line
  180.   inc   si
  181.   cmp   si,319                ;Are we at end of window?
  182.   jne   Verdergaan            ;Nope, then just continue.
  183.   xor   si,si                 ;else, initialise pointer
  184.   inc   si
  185. ifdef VOL
  186.   pop   cx
  187.   mov   ax,cx                 ;Calculate volume bar
  188.   mov   cl,160
  189.   div   cl
  190.   call  DrawVolume            ;Draw volume bar
  191.   xor   cx,cx                 ;Reset Volume bar
  192.   push  cx
  193. endif ;VOL
  194. Verdergaan:
  195. ifdef VOL
  196.   pop   cx
  197. endif ;VOL
  198.   xor   ax,ax
  199.   inc   ah
  200.   int   16h                   ;Anyone pressed a key?????
  201.   jz    oncemore              ;If not, just go on play Oscilloscope
  202.   mov   ax,3
  203.   int   10h                   ;Wipe screen and set VGA text mode. (80x25)
  204.   mov   ah,9
  205.   mov   dx,offset Text
  206.   int   21h                   ;Write compiled options on screen
  207.   xor   ax,ax
  208.   int   16h                   ;Wipe keyboard buffer
  209.   mov   ah,4ch
  210.   int   21h                   ;Leave this program and goto DOS (Bleahhh)
  211.  
  212. Paint Proc                    ;Paint a pixel in color AH
  213.   push  si                    ;Make sure our pointer isn't trashed.
  214.   push  ax                    ;Make sure color isn't forgotten
  215.   xor   ah,ah
  216.   inc   al
  217.   mov   cx,320                ;Calculate offset in screen segment of line
  218.   mul   cx                    ;to draw on.
  219.   mov   di,ax
  220.   add   di,si                 ;add for correct column.
  221.   pop   ax                    ;Get color back from stack
  222.   mov   [es:di],ah            ;Draw!!
  223.   pop   si
  224.   ret
  225. Paint Endp
  226.  
  227. ifdef VOL
  228. Add2VolumeBar Proc            ;Add a byte to the volume bar
  229.   push  ax                    ;Make sure the byte isn't forgotten, cause it's still needed.
  230.   cmp   al,80h                ;Calculate distance to no-sound
  231.   jb    LowByte
  232.   sub   al,80h
  233.   jmp   AddToBar
  234. LowByte:
  235.   push  dx
  236.   mov   dl,80h
  237.   sub   dl,al
  238.   mov   al,dl
  239.   pop   dx
  240. AddToBar:
  241.   xor   ah,ah
  242.   add   cx,ax                 ;Adjust volume bar (will be showed when at end
  243.   pop   ax                    ;of window)
  244.   ret
  245. Add2VolumeBar EndP
  246.  
  247. DrawVolume Proc               ;Draw the Volume Bar
  248.   push  si
  249. ifdef MAX ;*********************
  250.   push  ax
  251.   mov   bx,[ds:MaxVolume]
  252.   cmp   al,bl                 ;Is current volume harder then Max. Volume
  253.   jb    DoUpdateTime          ;if not, then update timer.
  254.   mov   [ds:MaxVolume],ax     ;if yes, then replace max. volume with current
  255.   xor   bx,bx
  256.   mov   [ds:KeepTime],bx      ;and reset timer.
  257. DoUpdateTime:
  258.   inc   word ptr [ds:Keeptime]          ;update timer
  259.   cmp   word ptr [ds:KeepTime],30       ;are we waiting long enough?
  260.   jne   DontDrawMaxBar                  ;not then don't update max. volume
  261.   mov   word ptr [ds:Keeptime],0        ;reset timer
  262.   pop   ax
  263.   push  ax
  264.   mov   [ds:MaxVolume],ax               ;Update max. volume
  265. DontDrawMaxBar:
  266.   pop   ax
  267. endif ;MAX ******************
  268.   mov   di,54401              ;Offset in screen segment for start of volume bar
  269.   xor   bx,bx
  270. DrawingLoop:
  271.   xor   cx,cx
  272.   cmp   bl,al                 ;Is there need to draw a color?
  273.   ja    NoColourChange        ;nope, then don't draw a color.
  274.   mov   cl,VolumeColor1
  275.   cmp   bl,70
  276.   jb    NoColourChange
  277.   mov   cl,VolumeColor2
  278. NoColourChange:
  279.   push  bx
  280.   add   bx,bx
  281.   mov   byte ptr [es:di+bx],cl          ;
  282.   mov   byte ptr [es:di+bx+320],cl      ;Draw the bar
  283.   mov   byte ptr [es:di+bx+640],cl      ;
  284.   mov   byte ptr [es:di+bx+960],cl      ;
  285.   mov   byte ptr [es:di+bx+1],cl        ;
  286.   mov   byte ptr [es:di+bx+321],cl      ;
  287.   mov   byte ptr [es:di+bx+641],cl      ;
  288.   mov   byte ptr [es:di+bx+961],cl      ;
  289.   pop   bx
  290.   inc   bx
  291.   cmp   bx,128                ;Is complete bar drawn??
  292.   jne   DrawingLoop           ;if not, draw on.
  293. ifdef MAX ;****************
  294.   call  DrawMaxVolume
  295. endif ;MAX ****************
  296.   pop   si
  297.   ret
  298. DrawVolume EndP
  299.  
  300. ifdef MAX ;****************
  301. DrawMaxVolume Proc            ;Draw Max. volume indicator.
  302.   push  si
  303.   push  bx
  304.   mov   si,54401              ;Initialise pointer
  305.   mov   bx,[ds:MaxVolume]     ;Get position
  306.   xor   bh,bh
  307.   cmp   bl,127
  308.   jb    NotToHard             ;To hard for bar (won't happen too often, I hope)
  309.   mov   bl,127                ;decrease volume to fit box.
  310. NotToHard:
  311.   add   si,bx
  312.   add   si,bx
  313.   mov   byte ptr [es:si],MaxColor       ;
  314.   mov   byte ptr [es:si+320],MaxColor   ;Draw max. volume indicator.
  315.   mov   byte ptr [es:si+640],MaxColor   ;
  316.   mov   byte ptr [es:si+960],MaxColor   ;
  317.   pop   bx
  318.   pop   si
  319.   ret
  320. DrawMaxVolume EndP
  321. endif ;MAX ****************
  322. endif ;VOL
  323.  
  324. DrawBorder Proc               ;Draw the border for osc. window.
  325.   mov   si,0
  326.   mov   cl,BorderColor
  327. TopLine:
  328.   mov   byte ptr [es:si],cl   ;Draw color 2
  329.   inc   si
  330.   cmp   si,320                ;Is complete top line drawn?
  331.   jne   TopLine               ;if not, continue the drawing process.
  332.   xor   dx,dx
  333.  Sides:
  334.   mov   byte ptr [es:si],cl             ;Draw Side Line left
  335.   mov   byte ptr [es:si+319],cl         ;Draw Side Line Right
  336.   add   si,320
  337.   inc   dx
  338.   cmp   dx,128                ;Are we ready drawing the sides?
  339.   jne   Sides                 ;if not, just go on drawing.
  340.   xor   dx,dx
  341. BottomLine:
  342.   mov   byte ptr [es:si],cl   ;Draw a pixel of bottom line
  343.   inc   si
  344.   inc   dx
  345.   cmp   dx,320                ;Is complete bottom line drawn?
  346.   jne   BottomLine            ;if not, draw on.
  347.  
  348. ifdef VOL
  349.   mov   si,54080              ;Pointer to start of line 169
  350.   xor   dx,dx
  351. VolumeTop:
  352.   mov   [es:si],cl            ;Draw pixel of volume window
  353.   inc   si
  354.   inc   dx
  355.   cmp   dx,258                ;Is topline ready
  356.   jne   VolumeTop             ;not, then draw on.
  357.   mov   si,54400              ;Pointer to start of line 170.
  358.   mov   [es:si],cl            ;
  359.   mov   [es:si+320],cl        ;Draw left side of box
  360.   mov   [es:si+640],cl        ;
  361.   mov   [es:si+960],cl        ;
  362.   add   si,257
  363.   mov   [es:si],cl            ;
  364.   mov   [es:si+320],cl        ;Draw right side of box
  365.   mov   [es:si+640],cl        ;
  366.   mov   [es:si+960],cl        ;
  367.   mov   si,55680
  368.   xor   dx,dx
  369. VolumeBottom:
  370.   mov   [es:si],cl            ;Draw bottom
  371.   inc   dx
  372.   inc   si
  373.   cmp   dx,258                ;Is bottom-line ready
  374.   jne   VolumeBottom          ;If not the draw on.
  375. endif ;VOL
  376.   ret
  377. drawBorder EndP
  378.  
  379. ifdef DET
  380. InitialiseSB Proc                       ;Init. SB and determine port addresses
  381.   mov   word ptr [b_port],210h
  382.   mov   word ptr [x_port],216h
  383.   mov   word ptr [w_port],21ch
  384.   mov   word ptr [r_port],21ah
  385.   mov   word ptr [a_port],21eh
  386. NotYetFound:
  387.   mov   dx,[ds:x_port]
  388.   mov   al,1
  389.   out   dx,al                           ;Send RESET
  390.   call  delay                           ;Wait must be approx. 3 ms is you have
  391.   xor   al,al                           ;a very fast computer you might need to
  392.   out   dx,al                           ;change the DELAY function
  393.   xor   cx,cx
  394. PollingLoop:
  395.   mov   dx,[ds:r_port]                  ;
  396.   in    al,dx                           ;Test SoundBlaster
  397.   inc   cx
  398.   cmp   cx,100
  399.   ja    FinishedPolling                 ;If tested 100 times stop testing.
  400.   cmp   al,READY                        ;Did sound blaster react
  401.   jne   PollingLoop                     ;If not, test again.
  402. FinishedPolling:
  403.   cmp   al,READY                        ;was there a reaction?
  404.   je    FoundBlaster                    ;If yes, we've got him.
  405.   add   word ptr [ds:b_port],10h        ;
  406.   add   word ptr [ds:x_port],10h        ;
  407.   add   word ptr [ds:w_port],10h        ;Update port addresses for new try
  408.   add   word ptr [ds:r_port],10h        ;
  409.   add   word ptr [ds:a_port],10h        ;
  410.   cmp   word ptr [ds:b_port],270h       ;Is base port address to high?
  411.   jne   NotYetFound                     ;if not, try polling again.
  412.   mov   ah,9                            ;if so, tell user there is no Sound
  413.   mov   dx,offset NoBlaster             ;blaster
  414.   int   21h
  415.   stc                                   ;Inform program of failure
  416.   ret
  417. FoundBlaster:
  418.   clc                                   ;Inform program of succes
  419.   ret
  420. InitialiseSB EndP
  421.  
  422. Delay Proc                    ;Delay
  423.   push  ax
  424.   xor   ax,ax
  425. DelayLoop1:
  426.   inc   ax
  427.   cmp   ax,0
  428.   jne   DelayLoop1
  429.   pop   ax
  430.   ret
  431. Delay EndP
  432.  
  433. endif ;DET
  434.  
  435. ifdef OVER
  436. TestCommandLine Proc
  437.   mov   bx,80h
  438.   mov   al,[ds:bx]                      ;Get length of command line
  439.   cmp   al,1
  440.   jna   NoCommandLine                   ;if there is no Com. Line skip testing
  441.   xor   cx,cx
  442.   mov   cl,al
  443.   xor   bx,bx
  444.   mov   si,82h                          ;DS:SI points to command line
  445. ReadComLine:
  446.   mov   al,[ds:si]
  447.   inc   si
  448.   inc   bx
  449.   cmp   al,2fh                          ;is character a /
  450.   je    commando                        ;then action follows
  451.   cmp   al,2dh                          ;is character a -
  452.   je    commando                        ;then action follows
  453.   cmp   bl,cl                           ;did we reach the end?
  454.   jbe   ReadComLine                     ;if not, continue testing
  455. NoCommandLine:
  456.   clc                                   ;tell program, Don't skip test part
  457.   ret
  458. commando:
  459.   mov   al,[ds:si]
  460.   cmp   al,3fh                          ;is command '?' then
  461.   je    ExplainThings                   ;explain command switches
  462.   and   al,0dfh                         ;make characters Upper case
  463.   cmp   al,42h                          ;is character 'B'
  464.   jne   ExplainThings                   ;if not, explain user the use of command switch.
  465.   mov   al,[ds:si+2]                    ;get parameter
  466.   sub   al,48                           ;
  467.   cmp   al,0                            ;
  468.   je    ExplainThings                   ;if not in valid range, explain
  469.   cmp   al,7
  470.   jnb   ExplainThings                   ;if not in valid range, explain
  471.   mov   cl,4
  472.   shl   al,cl
  473.   mov   ah,2
  474.   push  ax
  475.   mov   ax,@data
  476.   mov   ds,ax
  477.   pop   ax
  478.   mov   [ds:b_port],ax                  ;Set addresses
  479.   add   ax,6
  480.   mov   [ds:x_port],ax
  481.   add   ax,4
  482.   mov   [ds:r_port],ax
  483.   add   ax,2
  484.   mov   [ds:w_port],ax
  485.   add   ax,2
  486.   mov   [ds:a_port],ax
  487.   stc                                   ;tell program, skip testing for SB
  488.   ret
  489. ExplainThings:
  490.   mov   ax,@data
  491.   mov   ds,ax
  492.   mov   ah,9
  493.   mov   dx,offset ComOptions
  494.   int   21h                             ;display help text
  495.   xor   ax,ax
  496.   int   16h                             ;wait for keypress
  497.   clc
  498.   ret
  499. TestCommandLine EndP
  500. endif ;OVER
  501.  
  502. END
  503.